package com.cl.service;

import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.cl.auth.AuthException;
import com.cl.auth.stateless.StatelessToken;
import com.cl.request.*;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.JavaType;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cl.auth.AuthService;
import com.cl.auth.LoginVo;
import com.cl.auth.RefreshVo;
import com.cl.auth.stateless.StatelessUser;
import com.cl.dao.CommonDao;
import com.cl.dao.SearchDao;
import com.cl.dto.ComboTreeDTO;
import com.cl.dto.ObjectDTO;
import com.cl.dto.ResultDTO;
import com.cl.dto.UserDTO;
import com.cl.entity.AccessToken;
import com.cl.entity.CcPay;
import com.cl.entity.Image;
import com.cl.entity.Rel;
import com.cl.entity.UGroup;
import com.cl.entity.UUser;
import com.cl.entity.common.DBObject;
import com.cl.util.ClassNameReplaceUtil;
import com.cl.util.CommonUtil;
import com.cl.util.EntityNameReplaceUtil;
import com.cl.util.ExtJSFilter;
import com.cl.util.ExtJSSort;
import com.cl.util.HibernateUtil;
import com.cl.util.RelationFilter;

@Service
public class CommonService {

	static public  String PRIMARY_ID="primaryId";
	protected Logger log = LoggerFactory.getLogger(this.getClass());

	@Value("#{keyfieldProperties}")
	private HashMap<String, String> keyfield;

	@Value("#{applicationProperties['DEFAULT_DATE_FORMATE']}")
	public String DEFAULT_DATE_FORMATE;

	@SuppressWarnings("rawtypes")
	@Autowired
	private SearchDao searchDao;

	@Autowired
	private HibernateUtil hibernateUtil;

	@Autowired
	private CommonDao commonDao;

	@Autowired
	private DTOHelper dtoHelper;

	@Autowired
	private AuthService authService;

	@Autowired
	private CommonUtil commonUtil;

	@Autowired
	private PayCaculateService payCaculateService;

	/**
	 * 获得实体主键字段名
	 *
	 * @param entity
	 * @return
	 */
	public String getKeyField(String entity) {
		String key = keyfield.get(getEntityFullName(entity));
		if (key != null) {
			return key;
		} else {
			return "id";
		}
	}

	/**
	 * 补齐默认包路径全名
	 *
	 * @param entity
	 * @return
	 */
	private String getEntityFullName(String entity) {
		if (entity.indexOf(".") == -1) {
			return "com.cl.entity." + entity;
		} else {
			return entity;
		}
	}

	/**
	 * @param entity
	 * @return
	 * @throws ClassNotFoundException
	 */
	private Class<?> classForName(String entity) throws ClassNotFoundException {
		return Class.forName(getEntityFullName(entity));
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public ResultDTO listUsers(String kw, Integer limit) {
		ResultDTO dto = new ResultDTO<Object>();
		List ls = searchDao.listUsers(kw, limit);
		dto.total = ls.size();
		dto.data = ls;
		return dto;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public  ResultDTO listEntities(String entity_name, String property_name, String kw, Integer limit,String filter,String sort) throws ClassNotFoundException {
		ResultDTO dto = new ResultDTO<Object>();
		
		Class entity= classForName(entity_name);
		if(kw!=null && !kw.trim().equals("")){
			if(filter==null)
				filter = "[{\"property\":\""
						+property_name
						+"\",\"operator\":\"like\",\"value\":\""
						+kw+"\"}]";
			else{
				filter=filter.replace(']', ',')
						+"{\"property\":\""
						+property_name
						+"\",\"operator\":\"like\",\"value\":\""
						+kw+"\"}]";
			}
		}
		List<Criterion> criterions = getHibernateFilters(filter, entity);

		if(sort==null || (kw!=null  && !kw.trim().equals(""))){
			sort =" [{\"property\":\""
					+property_name+"\",\"direction\":\"ASC\"}]";
		}/*else{
			sort =sort.replace(']', ',')+" [{\"property\":\""
					+property_name+"\",\"direction\":\"ASC\"}]";
			
		}*/
		List<Order> orders = getHibernateOrders(sort);
		dto.data = searchDao.getEntities(0, limit, criterions, orders, entity);
		dto.total = dto.data.size();
		return dto;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public ResultDTO disticnt(String entity_name, String property_name, String kw, Integer limit,String filter) throws ClassNotFoundException {
		ResultDTO<Object> dto = new ResultDTO<Object>();
		Class entity= classForName(entity_name);
		if(kw!=null && !kw.trim().equals("")){
			if(filter==null)
				filter = "[{\"property\":\""
						+property_name
						+"\",\"operator\":\"like\",\"value\":\""
						+kw+"\"}]";
			else{
				filter=filter.replace(']', ',')
						+"{\"property\":\""
						+property_name
						+"\",\"operator\":\"like\",\"value\":\""
						+kw+"\"}]";
			}
		}
		List<Criterion> criterions = getHibernateFilters(filter, entity);
		
		List<Object> ls = searchDao.disticnt(entity, property_name, kw, limit,  criterions);
		dto.total = ls.size();
		List data = new ArrayList();
		for (int i = 0; i < dto.total; i++) {
			Object cur = ls.get(i);
			data.add(new Object[] { cur, cur });
		}
		dto.data = data;
		return dto;
	}

	public <T> ResultDTO<?> getEntities(int page, int start, int limit, String filter, String sort, String entity)
			throws ClassNotFoundException {
		return getEntities(page, start, limit, filter, sort, classForName(entity));
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public <T> ResultDTO getEntities(int page, int start, int limit, String filter, String sort, Class<T> entity) {
		ResultDTO dto = new ResultDTO();
		List<Criterion> criterions = getHibernateFilters(filter, entity);
		dto.total = searchDao.getEntityTotal(criterions, entity);
		List<Order> orders = getHibernateOrders(sort);
		dto.data = searchDao.getEntities(start, limit, criterions, orders, entity);
		return dto;
	}

	@SuppressWarnings("unchecked")
	public <T> T updateEntity(String entity, Map<String, Object> request, String ip) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		return updateEntity((Class<T>) classForName(entity), request, ip);
	}

	public <T> T updateEntity(Class<T> entityClass, Map<String, Object> request, String ip)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		String idProperty = getKeyField(entityClass.getSimpleName());// 获取主键ID PROPERTY
		Object id = getPrimaryValue(entityClass, idProperty, request.get(idProperty));// 获取主健ID VALUE
		T entity = getEntity(entityClass.getSimpleName(), id, ip);// 获取ENTITY
		if (entity != null) {
			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entity);
			// 注册时间属性转换器
			beanWrapper.registerCustomEditor(Date.class, new CustomDateEditor(
					new SimpleDateFormat(DEFAULT_DATE_FORMATE), true));
			beanWrapper.setPropertyValues(request);
			String currentUserID = commonUtil.getCurrentUserID();
			commonDao.saveDBOject((DBObject) entity, String.valueOf(request), currentUserID, ip);
		}
		return entity;
	}

	@SuppressWarnings({ "unchecked" })
	public <T> List<T> getRelEntities(String entity, String filter) throws ClassNotFoundException {
		return this.getRelEntities((Class<T>) classForName(entity), filter, getKeyField(entity));
	}

	/**
	 * 获取关联数据
	 *
	 * @param clazz
	 * @param filter
	 * @param idProperty
	 * @param <T>
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T> List<T> getRelEntities(Class<T> clazz, String filter, String idProperty) {
		List<T> relEntities = null;
		if ((filter != null) && !"".equals(filter)) {
			String className = clazz.getSimpleName();// 类名
			String entity2 = className.toUpperCase();// 关联的关键字

			Map filters = getRelFilters(filter);
			if (filters != null) {
				Object id = filters.get("relId");// 从filter中获取
				Object entity = filters.get("relEntity");// 从filter中获取
				if ((id != null) && (entity != null)) {
					Long id1 = Long.parseLong(String.valueOf(id));
					String entity1 = String.valueOf(entity);
					entity1 = EntityNameReplaceUtil.replaceName(entity1);
					entity2 = EntityNameReplaceUtil.replaceName(entity2);
					relEntities = searchDao.getRelEntities(clazz, className, id1, entity1, entity2, idProperty);
				}
			}
		}
		return relEntities;
	}

	@SuppressWarnings("unchecked")
	public <T> T getEntity(String entity, Object kval, String ip) throws ClassNotFoundException {
		return getEntity((Class<T>) classForName(entity), kval, ip);
	}

	/**
	 * @param entityClass
	 * @param kval
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getEntity(Class<T> entityClass, Object kval, String ip) {
		T obj = null;
		try {
			String currentUserID = commonUtil.getCurrentUserID();
			if (kval == null) {
				obj = entityClass.newInstance();
				
				commonDao.saveDBOject((DBObject) obj, null, currentUserID, ip);

			} else {
				obj = (T) searchDao.getEntity(entityClass, kval);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * @param entityClass
	 * @param request
	 * @param idProperty
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T updateEntity(Class<T> entityClass, Map<String, Object> request, String idProperty, String ip) {
		if ((request != null) && (request.get(idProperty) != null)) {
			Object id = getPrimaryValue(entityClass, idProperty, request.get(idProperty));
			T entity = (T) searchDao.getEntity(entityClass, id);// 获取更新的ENTITY
			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entity);
			// 注册时间属性转换器
			beanWrapper.registerCustomEditor(Date.class, new CustomDateEditor(
					new SimpleDateFormat(DEFAULT_DATE_FORMATE), true));
			beanWrapper.setPropertyValues(request);
			commonDao.saveDBOject((DBObject) entity, String.valueOf(request), commonUtil.getCurrentUserID(), ip);
			return entity;
		} else {
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public <T> T   setEntityProp(T entity, Map<String, Object> request, String ip) {
		if(!request.containsKey(PRIMARY_ID))
			return entity;
		BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entity);
		// 注册时间属性转换器
		beanWrapper.registerCustomEditor(Date.class, new CustomDateEditor(
				new SimpleDateFormat(DEFAULT_DATE_FORMATE), true));
		String idProperty = getKeyField(entity.getClass().getSimpleName());// 获取主键ID PROPERTY
		
		request.remove(idProperty);
		request.remove(PRIMARY_ID);

		beanWrapper.setPropertyValues(request);
		commonDao.saveDBOject((DBObject) entity, String.valueOf(request), commonUtil.getCurrentUserID(), ip);
		return entity;
	}
	
	/**
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public List<Rel> addRel(RelRequest request, String ip) {
		List<Rel> relList = new ArrayList<Rel>();
		List<Long> id2 = request.id2;
		if ((id2 != null) && (id2.size() > 0)) {
			String userId = commonUtil.getCurrentUserID();
			// 获取最大ord排序号
			int maxOrd = searchDao.getMaxOrd(request.id1, request.entity1, request.entity2);
			for (int i = 0; i < id2.size(); i++) {
				Rel rel = new Rel();
				rel.setId1(request.id1);
				rel.setEntity1(request.entity1);
				rel.setId2(id2.get(i));
				rel.setEntity2(request.entity2);
				List<Rel> rels = searchDao.getRels(rel);
				// 若不存在记录时，才会SAVE
				if ( rels == null || rels.isEmpty()) {
					rel.setOrd(new BigDecimal(++ maxOrd));
					commonDao.saveDBOject(rel, getObjJson(rel), userId, ip);
					relList.add(rel);
				}
			}
		}
		return relList;
	}

	/**
	 * @param request
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void deleteRel(RelRequest request, String ip) {
		// 查询是否已关联
		// 若存在则删除关联关系，不存在不作操作
		List<Long> id2 = request.id2;
		if ((id2 != null) && (id2.size() > 0)) {
			String userId = commonUtil.getCurrentUserID();
			for (int i = 0; i < id2.size(); i++) {
				Rel rel = new Rel();
				rel.setId1(request.id1);
				rel.setEntity1(request.entity1);
				rel.setId2(id2.get(i));
				rel.setEntity2(request.entity2);
				List<Rel> rels = searchDao.getRels(rel);
				if ((rels != null) && (rels.size() > 0)) {
					for (int j = 0; j < rels.size(); j++) {
						commonDao.deleteDBObject(rels.get(j), getObjJson(rels.get(j)), userId, ip);
					}
				}
			}
		}
	}

	/**
	 * @param request
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public <T> void deleteEntities(RemoveRequest request, String ip) {
		// 删除entity及相关的关联信息
		List<Object> ids = request.id;
		Class<T> clazz = null;
		try {
			clazz = (Class<T>) Class.forName("com.cl.entity." + request.entity);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		if ((clazz != null) && (ids != null) && (ids.size() > 0)) {
			String userId = commonUtil.getCurrentUserID();
			for (int i = 0; i < ids.size(); i++) {
				Object id = getPrimaryValue(clazz, request.idProperty, ids.get(i));
				DBObject obj = (DBObject) searchDao.getEntity(clazz, id);
				if (obj != null) {
					commonDao.deleteDBObject(obj, getObjJson(obj), userId, ip);
					String entity = request.entity.toUpperCase();
					
					//兼容历史数据对REL表中THESIS_CATALOG的特殊处理
					if(entity.contains("THESISCATALOG")){
						entity = entity.replace("THESISCATALOG", "THESIS_CATALOG");
					}
					
					List<Rel> rels = searchDao.getAllRels(entity, id);
					if ((rels != null) && (rels.size() > 0)) {
						for (int j = 0; j < rels.size(); j++) {
							commonDao.deleteDBObject(rels.get(j), getObjJson(rels.get(j)), userId, ip);
						}
					}
					
					
				}
			}
		}
	}

	/**
	 * @param filter
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Map getRelFilters(String filter) {
		Map map = null;
		if ((filter != null) && !"".equals(filter)) {
			ObjectMapper objectMapper = new ObjectMapper();
			JavaType type = objectMapper.getTypeFactory()
					.constructParametricType(ArrayList.class, RelationFilter.class);
			try {
				List<RelationFilter> filters = (List<RelationFilter>) objectMapper.readValue(filter, type);
				if (filters.size() == 1) {
					RelationFilter relFilter = filters.get(0);
					if ((relFilter != null) && relFilter.isExactMatch()) {
						String property = relFilter.getProperty();
						String id = property.substring(0, property.length() - 2).toUpperCase();// docId
						map = new HashMap();
						map.put("relEntity", id);
						map.put("relId", relFilter.getValue());
					}
				}
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return map;
	}

	/**
	 * @param filter
	 * @param entity
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> List<Criterion> getHibernateFilters(String filter, Class<T> entity) {
		List<Criterion> criterias = null;
		if ((filter != null) && !"".equals(filter)) {
			ObjectMapper objectMapper = new ObjectMapper();
			JavaType type = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ExtJSFilter.class);
			List<ExtJSFilter> filters;
			try {
				filters = (List<ExtJSFilter>) objectMapper.readValue(filter, type);
				criterias = getCriteriaList(filters, entity);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			}
		}
		return criterias;
	}

	/**
	 * @param filters
	 * @param entity
	 * @return
	 * @throws SecurityException
	 * @throws ParseException
	 * @throws NoSuchFieldException
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	private <T> List<Criterion> getCriteriaList(List<ExtJSFilter> filters, Class<T> entity) throws SecurityException,
			ParseException, NoSuchFieldException, JsonParseException, JsonMappingException, IOException {
		List<Criterion> criterias = new ArrayList<Criterion>();
		if (filters != null) {
			criterias = hibernateUtil.getRestrictions(filters, entity);
		}
		return criterias;
	}

	/**
	 * @param sort
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Order> getHibernateOrders(String sort) {
		List<Order> orders = null;
		if ((sort != null) && !"".equals(sort)) {
			ObjectMapper objectMapper = new ObjectMapper();
			JavaType type = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ExtJSSort.class);
			List<ExtJSSort> sorts;
			try {
				sorts = (List<ExtJSSort>) objectMapper.readValue(sort, type);
				orders = getOrderList(sorts);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			}
		}
		return orders;
	}

	/**
	 * @param sorts
	 * @return
	 */
	private List<Order> getOrderList(List<ExtJSSort> sorts) {
		List<Order> orders = new ArrayList<Order>();
		if (sorts != null) {
			orders = hibernateUtil.getOrders(sorts);
		}
		return orders;
	}

	/**
	 * @param entityClass
	 * @param property
	 * @param value
	 * @return
	 */
	private <T> Object getPrimaryValue(Class<T> entityClass, String property, Object value) {
		try {
			Field classField = entityClass.getDeclaredField(property);
			DefaultConversionService conversionService = new DefaultConversionService();
			return conversionService.convert(value, classField.getType());
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @param obj
	 * @return
	 */
	private String getObjJson(Object obj) {
		String json = null;
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			json = objectMapper.writeValueAsString(obj);
		} catch (JsonGenerationException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}

	/**
	 * @param loginCommand
	 * @return
	 */
	public UserDTO login(LoginVo loginCommand) {
		if ((loginCommand!=null) && loginCommand.accessToken!=null) {
			StatelessToken token = new StatelessToken(loginCommand.accessToken, true);
			Subject subject = SecurityUtils.getSubject();
			StatelessUser user = null;
			try {
				subject.login(token);
				user = authService.getUser(loginCommand.accessToken);
			} catch(Exception e) {
				throw new AuthException("用户名或密码不正确！", e);
			}
			return dtoHelper.buildUserDTO(user);
		} else {
			AccessToken token = authService.login(loginCommand);
			UUser loginUser = commonUtil.getUser();// 通过pwd认证
			UGroup group = null;
			if (loginUser != null) {
				group = loginUser.getUgroup();
			}
			// group = searchDao.getUserGroupByID(loginUser.getGid().longValue());
			loginUser.setOrgName(commonUtil.getUserOrgNameByID(loginUser.getOrgId()));
			loginUser.setOfficeName(commonUtil.getUserOfficeNameByID(loginUser.getOrgId()));
			// c4w
			String pwdnew = loginCommand.pwdnew;
			if (pwdnew != null) {
				loginUser.setPwd(new Md5Hash(pwdnew).toString());
			}
			commonDao.saveDBOject(loginUser);
			return dtoHelper.buildUserDTO(loginUser, group, token);
		}
	}

	/**
     *
     */
	public void logout(String token) {
		authService.logout(token);
	}

	/**
	 * @param refreshCommand
	 * @return
	 */
	public AccessToken refresh(RefreshVo refreshCommand) {
		return authService.refresh(refreshCommand);
	}

	/**
	 * 创建新用户
	 * 
	 * @param request
	 * @param ip
	 * @return
	 */
	public UUser createUser(Map<String, Object> request, String ip) {
		UUser user = new UUser();
		if ((request != null) && request.containsKey("id")) {
			request.remove("id");
		}
		request.put("gid", 5);// 默认是其它
		// 　去掉主健
		BeanWrapperImpl beanWrapper = new BeanWrapperImpl(user);
		// 注册时间属性转换器
		beanWrapper.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(DEFAULT_DATE_FORMATE),
				true));
		beanWrapper.setPropertyValues(request);
		commonDao.saveDBOject(user, String.valueOf(request), commonUtil.getCurrentUserID(), ip);
		return user;
	}

	/**
	 * 更新用户信息
	 * 
	 * @param id
	 * @param request
	 * @param ip
	 * @return
	 */
	public UUser updateUser(Object id, Map<String, Object> request, String ip) {
		if ((request != null) && request.containsKey("id")) {// 如果存在主健
			Object primaryValue = getPrimaryValue(UUser.class, "id", request.get("id"));
			UUser entity = (UUser) searchDao.getEntity(UUser.class, primaryValue);// 获取更新的ENTITY
			if (request.containsKey("pwd")) {
				request.put("pwd", new Md5Hash(request.get("pwd")).toString());
			}
			BeanWrapperImpl beanWrapper = new BeanWrapperImpl(entity);
			// 注册时间属性转换器
			beanWrapper.registerCustomEditor(Date.class, new CustomDateEditor(
					new SimpleDateFormat(DEFAULT_DATE_FORMATE), true));
			beanWrapper.setPropertyValues(request);
			commonDao.saveDBOject(entity, String.valueOf(request), commonUtil.getCurrentUserID(), ip);
			return entity;
		}
		return null;
	}

	public ResultDTO getWorkLoadEntities(String filter) {
		ResultDTO dto = new ResultDTO();
		String jpql = getWorkLoadJpql(filter);
		dto.data = searchDao.getWorkLoad(jpql);
		if ((dto.data != null) && (dto.data.size() > 0)) {
			dto.total = dto.data.size();
		}
		return dto;
	}

	private String getWorkLoadJpql(String filter) {
		StringBuffer jpql = new StringBuffer();
		if ((filter != null) && !"".equals(filter)) {
			ObjectMapper objectMapper = new ObjectMapper();
			JavaType type = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ExtJSFilter.class);
			List<ExtJSFilter> filters;
			try {
				filters = (List<ExtJSFilter>) objectMapper.readValue(filter, type);
				for (ExtJSFilter item : filters) {
					jpql.append(" and ");
					jpql.append(hibernateUtil.getJpqlDateValue(item));
				}
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return jpql.toString();
	}

	/**
	 *
	 * @param request
	 * @return
	 */
	@Transactional
	public List<CcPay> confirmPays(PayRequest request, String ip) {
		List<CcPay> list = new ArrayList<CcPay>();
		if ((request.ids != null) && (request.ids.size() > 0)) {
			String simpleUserId = commonUtil.getCurrentSimpleUserID();
			String userId = commonUtil.getCurrentUserID();
			for (int i = 0; i < request.ids.size(); i++) {
				Long payId = ((request.ids).get(i));
				CcPay obj = (CcPay) searchDao.getEntity(CcPay.class, payId);
				if(!"editor".equals(request.field)) {
					obj.setRewardCMan(simpleUserId);
					obj.setRewardCTime(new Date());
//					obj.setRewardFlag("Y");
					obj.setRewardFlag(true);
				} else {
					obj.setReEditorCFlag(true);
					obj.setReEditorCMan(simpleUserId);
					obj.setReEditorCTime(new Date());
				}
				commonDao.saveDBOject(obj, getObjJson(obj), userId, ip);
				list.add(obj);
			}
		}
		return list;
	}
	
	/**
	 * 管理员批量确认检索结果
	 * @param filter
	 * @param ip
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void batchConfirmPays(Map<String, Object> request, String ip) {
		String filter = (String)request.get("filter");
		List<Criterion> criterions = getHibernateFilters(filter, CcPay.class);
		List<CcPay> ccPays = searchDao.getAllEntities(criterions, null, CcPay.class);
		if(ccPays !=null && !ccPays.isEmpty()) {
			String simpleUserId = commonUtil.getCurrentSimpleUserID();
			String userId = commonUtil.getCurrentUserID();
			for (CcPay pay:ccPays) {
				if( pay!=null) {
					pay.setRewardCMan(simpleUserId);
					pay.setRewardCTime(new Date());
					pay.setRewardFlag(true);
					commonDao.saveDBOject(pay, getObjJson(pay), userId, ip);
				}
			}
		}
	}
	
	/**
	 * 编辑批量确认检索结果
	 * @param request
	 * @param ip
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("rawtypes")
	@Transactional
	public void batchEditorConfirmPays(Map<String, Object> request, String ip) throws ClassNotFoundException {
		String filter = (String)request.get("filter");
		if (!StringUtils.isEmpty(filter)) {
			filter = filter.replaceAll("thesiId", "thesisId");
		}
		List ccPays = getRelEntities("CcPay", filter);
		if(ccPays !=null && !ccPays.isEmpty()) {
			String simpleUserId = commonUtil.getCurrentSimpleUserID();
			String userId = commonUtil.getCurrentUserID();
			for (Object obj:ccPays) {
				if( obj!=null) {
					CcPay pay = (CcPay)obj;
					pay.setReEditorCFlag(true);
					pay.setReEditorCMan(simpleUserId);
					pay.setReEditorCTime(new Date());
					commonDao.saveDBOject(pay, getObjJson(pay), userId, ip);
				}
			}		
		}
	}


//	/**
//	 *
//	 * @param request
//	 * @param ip
//	 * @return
//	 */
//	@Transactional
//	public List<CcPay> editConfirmPays(PayRequest request, String ip) throws Exception {
//		List<CcPay> list = new ArrayList<CcPay>();
//		if ((request.ids != null) && (request.ids.size() > 0)) {
//			String simpleUserId = commonUtil.getCurrentSimpleUserID();
//			String userId = commonUtil.getCurrentUserID();
//			for (int i = 0; i < request.ids.size(); i++) {
//				Long payId = ((request.ids).get(i));
//				CcPay obj = (CcPay) searchDao.getEntity(CcPay.class, payId);
//				BigDecimal docNumber = obj.getDocNumber();
//				BigDecimal reward = obj.getReward();
//				if ((reward == null) || (reward.intValue() == 0)) {
//					reward = new BigDecimal(payCaculateService.getPayValue(obj));
//					obj.setReward(reward);
//				}
////				obj.setReEditorCFlag("Y");
//				obj.setReEditorCFlag(true);
//				obj.setReEditorCMan(simpleUserId);
//				obj.setReEditorCTime(new Date());
//				commonDao.saveDBOject(obj, getObjJson(obj), userId, ip);
//				list.add(obj);
//			}
//		}
//		return list;
//	}
//
//	/**
//	 *
//	 * @param request
//	 * @param ip
//	 * @return
//	 */
//	@Transactional
//	public List<CcPay> updatePays(EditPayRequest request, String ip) {
//		List<CcPay> list = new ArrayList<CcPay>();
//		if ((request != null) && (request.pays != null) && (request.pays.size() > 0)) {
//			String simpleUserId = commonUtil.getCurrentSimpleUserID();
//			String userId = commonUtil.getCurrentUserID();
//			for (int i = 0; i < request.pays.size(); i++) {
//				EditPay editPay = (request.pays.get(i));
//				CcPay obj = (CcPay) searchDao.getEntity(CcPay.class, editPay.id);
//				obj.setDocNumber(editPay.docNumber);
//				obj.setReward(editPay.reward);
//				commonDao.saveDBOject(obj, getObjJson(obj), userId, ip);
//				list.add(obj);
//			}
//		}
//		return list;
//	}

	public List<CcPay> caculatePay(String entity, Object kval, String ip) throws Exception {
		//List<CcPay> pays = searchDao.getRelPays(entity, kval);
		Class payClass = CcPay.class;
		//List<CcPay> pays = searchDao.getRelEntities(payClass, "CcPay", (Long) kval, entity.toUpperCase(), "CCPAY", "id");
		//只计算未发放稿酬
		List<CcPay> pays = searchDao.getRelPaysFromRel((Long)kval, entity.toUpperCase());
		
		String userId = commonUtil.getCurrentSimpleUserID();
		
		//取得文稿影像实体类和实体
		DBObject obj = getEntity(entity,kval,ip);
		Class clazz = classForName(entity);
		ObjectDTO objDTO = new ObjectDTO(clazz,obj);
		
		for (CcPay pay : pays) {
//0217			//0215
//			String c=ClassNameReplaceUtil.replaceName1(pay.getClass_());
//			pay.setClass_(c);
			String reward = payCaculateService.getPayValue(pay,objDTO);
			pay.setReward(new BigDecimal(reward));
//0217			//0215
//			String c1=ClassNameReplaceUtil.replaceName1(pay.getClass_());
//			pay.setClass_(c1);
			commonDao.updatePay(pay, userId, ip);
		}

		return pays;
	}
	//由于Rels不会太多 <20，全部重新排序简单可靠
	public List<Rel> dragDropSort(String associatedName, Long associatedID, String relatedName, List<Long> newOrder) {
		List<Rel> rels = searchDao.getRelsOrder(associatedName, associatedID, relatedName, newOrder);
		HashMap<Long,Rel> rm = new HashMap<Long,Rel>();
		for(Rel r:rels){
			rm.put(r.getId2(), r);
		}
		for(int i=0; i<newOrder.size();i++){
			Rel r = rm.get(newOrder.get(i));
			r.setOrd(new BigDecimal(i));
			commonDao.saveDBOject(r);
		}
		return rels;
	}

	
	
	/**
	 * 拖拽排序
	 * @param sort
	 */
	public void dragDropSort(OrderRequest sort) {		
		dragDropSort(sort.associatedName, sort.associatedID, sort.relatedName, sort.dragObj);
	}
	
	public List<ComboTreeDTO> getTreeData(String entity_name, String property_name, String filter) 
			throws ClassNotFoundException{
		List<ComboTreeDTO> result = new ArrayList<ComboTreeDTO>();
		Class entity= classForName(entity_name);
		//通过textSet避免树构造节点重复
		Set<String> textSet = new HashSet<String>();
		
		List<Criterion> criterions = getHibernateFilters(filter, entity);
		
		List<Object> list = searchDao.disticnt(entity, property_name,null,null,criterions);
		
		List<String> types = new ArrayList<String>();
		//第一次遍历处理多分类（包含;）的情况，将多分类拆分
		for(int i=0; i<list.size(); i++){
			String classa = (String) list.get(i);
			if (classa != null && !classa.isEmpty()) {
				if (classa.contains(";")) {
					String[] classaes = StringUtils.split(classa, ';');
					types.addAll(Arrays.asList(classaes));
				} else
					types.add(classa);
			}
		}
		
		for(int i=0; i<types.size(); i++){
			String classa =  types.get(i);
			//对层次分类的树形转换进行特殊处理
			if(classa.contains("#")){
				String[] classes = StringUtils.split(classa, '#');
				ComboTreeDTO root;
				if(!textSet.contains(classes[0])){
					ComboTreeDTO node = new ComboTreeDTO(classes[0]);
					result.add(node);
					textSet.add(node.text);
					root = node;
				}else{
					root = ComboTreeDTO.findInListByText(result, classes[0]);
				}
				
				for(int j=1; j<classes.length; j++){
					String text = classes[j-1]+"#"+classes[j];
					if(!textSet.contains(text)){
						
						ComboTreeDTO parent = root.findNodeByText(classes[j-1]);
						parent.leaf = false;
						parent.cls = "folder";
						
						ComboTreeDTO child = new ComboTreeDTO(classes[j]);
						parent.addChild(child);
						textSet.add(text);
					}
				}
			}else{
				
				if(!textSet.contains(classa)){
					ComboTreeDTO node = new ComboTreeDTO(classa);
					result.add(node);
					textSet.add(node.text);
				}
			}
		}
		return result;
	}
	
	
}
